package com.yixia.camera;

import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.util.Log;

import com.yixia.camera.model.MediaObject.MediaPart;
import com.yixia.camera.util.VideoUtil;

import java.io.File;
import java.io.IOException;
import java.util.TreeSet;

/**
 * 使用系统MediaRecorder录制，适合低端机
 *
 * @author yixia.com
 */
public class MediaRecorderSystem extends MediaRecorderBase implements android.media.MediaRecorder
        .OnErrorListener {

    /**
     * 系统MediaRecorder对象
     */
    private android.media.MediaRecorder mMediaRecorder;
    private TreeSet<String> mVideoPath = new TreeSet<String>();

    public MediaRecorderSystem() {
        initMediaRecord();
    }

    private void initMediaRecord() {
        if (mMediaRecorder == null) {
            mMediaRecorder = new MediaRecorder();
            mMediaRecorder.setOnErrorListener(this);
            mMediaRecorder.setOrientationHint(90);//=================设置摄像头90度=============
        }
    }

    /**
     * 开始录制
     */
    @Override
    public MediaPart startRecord() {
        if (mMediaObject != null && mSurfaceHolder != null && !mRecording) {
            MediaPart result = mMediaObject.buildMediaPart(mCameraId, ".mp4");

            try {
                initMediaRecord();

                // Step 1: Unlock and set mCamera to MediaRecorder
                mCamera.unlock();
                mMediaRecorder.setCamera(mCamera);
                mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());


                // Step 2: Set sources
                mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);//before
                // setOutputFormat()
                mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//before
                // setOutputFormat()

                mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

                //设置视频输出的格式和编码
                CamcorderProfile mProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
                //                mMediaRecorder.setProfile(mProfile);
                mMediaRecorder.setVideoSize(640, 480);//after setVideoSource(),after setOutFormat()
                mMediaRecorder.setAudioEncodingBitRate(44100);
                if (mProfile.videoBitRate > 2 * 1024 * 1024)
                    mMediaRecorder.setVideoEncodingBitRate(2 * 1024 * 1024);
                else mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate);
                mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate);//after setVideoSource
                // (),after setOutFormat()

                mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//after
                // setOutputFormat()
                mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);//after
                // setOutputFormat()

                //mMediaRecorder.setVideoEncodingBitRate(800);

                // Step 4: Set output file
                mMediaRecorder.setOutputFile(result.mediaPath);

                // Step 5: Set the preview output
                //				mMediaRecorder.setOrientationHint(90);//加了HTC的手机会有问题

                Log.e("Yixia", "OutputFile:" + result.mediaPath);
                //因为间歇录视频,可以删除最近的一小段视频,比如0,1,2,删除了2,再录下一段的路径还是2,防止路径存储重复
                mVideoPath.add(result.mediaPath);

                mMediaRecorder.prepare();
                mMediaRecorder.start();
                mRecording = true;
                return result;
            } catch (IllegalStateException e) {
                e.printStackTrace();
                Log.e("Yixia", "startRecord", e);
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("Yixia", "startRecord", e);
            } catch (Exception e) {
                e.printStackTrace();
                Log.e("Yixia", "startRecord", e);
            }
        }
        return null;
    }

    /**
     * 停止录制
     */
    @Override
    public void stopRecord() {
        long endTime = System.currentTimeMillis();
        if (mMediaRecorder != null) {
            //设置后不会崩
            mMediaRecorder.setOnErrorListener(null);
            mMediaRecorder.setPreviewDisplay(null);
            try {
                mMediaRecorder.stop();
            } catch (IllegalStateException e) {
                Log.w("Yixia", "stopRecord", e);
            } catch (RuntimeException e) {
                Log.w("Yixia", "stopRecord", e);
            } catch (Exception e) {
                Log.w("Yixia", "stopRecord", e);
            }
        }

        if (mCamera != null) {
            try {
                mCamera.lock();
            } catch (RuntimeException e) {
                Log.e("Yixia", "stopRecord", e);
            }
        }

        // 判断数据是否处理完，处理完了关闭输出流
        if (mMediaObject != null) {
            MediaPart part = mMediaObject.getCurrentPart();
            if (part != null && part.recording) {
                part.recording = false;
                part.endTime = endTime;
                part.duration = (int) (part.endTime - part.startTime);
                part.cutStartTime = 0;
                part.cutEndTime = part.duration;
            }
        }
        mRecording = false;
    }

    /**
     * 释放资源
     */
    @Override
    public void release() {
        super.release();
        if (mMediaRecorder != null) {
            mMediaRecorder.setOnErrorListener(null);
            try {
                mMediaRecorder.release();
            } catch (IllegalStateException e) {
                Log.w("Yixia", "stopRecord", e);
            } catch (Exception e) {
                Log.w("Yixia", "stopRecord", e);
            }
        }
        mMediaRecorder = null;
    }

    @Override
    public void onError(MediaRecorder mr, int what, int extra) {
        try {
            if (mr != null) mr.reset();
        } catch (IllegalStateException e) {
            Log.w("Yixia", "stopRecord", e);
        } catch (Exception e) {
            Log.w("Yixia", "stopRecord", e);
        }
        if (mOnErrorListener != null) mOnErrorListener.onVideoError(what, extra);
    }

    /**
     * 不需要视频数据回调
     */
    @Override
    protected void setPreviewCallback() {
        //super.setPreviewCallback();
    }

    /**
     * 合并视频文件
     */
    @Override
    protected void concatVideoParts() {
        mVideoAppendHanlder.removeMessages(VIDEO_APPEND_COMPLETE);
        mVideoAppendHanlder.removeMessages(VIDEO_APPEND_START);
        if (mVideoPath != null && mVideoPath.size() > 0) {
            com.yixia.camera.util.Log.e("合并视频的地址:" + mVideoPath.toString());
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        VideoUtil.appendVideo(mMediaObject.getOutputDirectory() + "/append.mp4",
                                mVideoPath);
                        //删除那些块文件
                        File videoPart;
                        for (String path : mVideoPath) {
                            videoPart = new File(path);
                            if (videoPart.exists()) {
                                videoPart.delete();
                            }
                        }
                        mVideoAppendHanlder.sendEmptyMessage(VIDEO_APPEND_COMPLETE);
                    } catch (IOException e) {
                        com.yixia.camera.util.Log.e("合并视频出现问题");
                        e.printStackTrace();
                    } finally {
                        mVideoPath.clear();
                    }
                }
            }).start();
        } else {
            com.yixia.camera.util.Log.e("合并视频已经完成或者part视频有问题");
        }

    }

}
